﻿using Microsoft.Extensions.Logging;
using RotovapPlatform.Domain.Business.Recipes.Entities;
using RotovapPlatform.Domain.Business.Recipes.Entities.Parameters;
using RotovapPlatform.Domain.Business.Storage.Enums;
using RotovapPlatform.Domain.Services.DeviceParameters;
using RotovapPlatform.Domain.Services.Storages;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace RotovapPlatform.Domain.Recipes.Services;

/// <summary>
/// 配方领域服务实现
/// </summary>
public class RecipeDomainService : IRecipeDomainService
{
	private readonly ILogger<RecipeDomainService> _logger;
	private readonly IStorageDomainService _storageDomainService;
	private readonly IDeviceParameterDomainService _deviceParameterService;

	public RecipeDomainService(
		ILogger<RecipeDomainService> logger,
		IStorageDomainService storageDomainService,
		IDeviceParameterDomainService deviceParameterService)
	{
		_logger = logger;
		_storageDomainService = storageDomainService;
		_deviceParameterService = deviceParameterService;
	}

	public (bool IsValid, string ErrorMessage) ValidateRecipe(RecipeDefinition recipe)
	{
		if (recipe == null)
			return (false, "配方不能为空");

		if (string.IsNullOrWhiteSpace(recipe.ExperimentName))
			return (false, "配方名称不能为空");

		if (recipe.RotovapParameters == null)
			return (false, "旋蒸参数不能为空");

		// 验证产物参数
		var (isValid, error) = ValidateProductParameters(recipe.RotovapParameters.ProductParameters);
		if (!isValid)
			return (false, error);

		// 验证清洗参数
		if (recipe.RotovapParameters.CleaningParameters != null)
		{
			var cleaningParams = recipe.RotovapParameters.CleaningParameters;

			// 验证冷凝管清洗参数
			if (cleaningParams.IsCondensationClean)
			{
				if (string.IsNullOrEmpty(cleaningParams.CondensationCleaningSolution))
					return (false, "请选择冷凝管清洗液");

				if (cleaningParams.CondensationCleaningVolume <= 0)
					return (false, "冷凝管清洗体积必须大于0");

				if (cleaningParams.CondensationCleaningSpeed <= 0)
					return (false, "冷凝管清洗速度必须大于0");
			}

			// 验证旋转瓶清洗参数
			if (cleaningParams.IsRotaryBottleClean)
			{
				if (string.IsNullOrEmpty(cleaningParams.RotaryBottleCleaningSolution))
					return (false, "请选择旋转瓶清洗液");

				if (cleaningParams.RotaryBottleCleaningVolume <= 0)
					return (false, "旋转瓶清洗体积必须大于0");

				if (cleaningParams.RotaryBottleCleaningTime <= 0)
					return (false, "旋转瓶清洗时间必须大于0");
			}
		}

		return (true, string.Empty);
	}

	/// <summary>
	/// 异步验证配方参数
	/// </summary>
	/// <param name="recipe">待验证的配方</param>
	/// <returns>验证结果和错误信息</returns>
	public async Task<(bool IsValid, string ErrorMessage)> ValidateRecipeAsync(RecipeDefinition recipe)
	{
		try
		{
			// 基本验证
			if (recipe == null)
				return (false, "配方不能为空");

			if (string.IsNullOrWhiteSpace(recipe.ExperimentName))
				return (false, "配方名称不能为空");

			if (recipe.RotovapParameters == null)
				return (false, "旋蒸参数不能为空");

			// 验证产物参数
			var (isValid, error) = await ValidateProductParametersAsync(recipe.RotovapParameters.ProductParameters);
			if (!isValid)
				return (false, error);

			// 验证清洗参数
			if (recipe.RotovapParameters.CleaningParameters != null)
			{
				var cleaningParams = recipe.RotovapParameters.CleaningParameters;

				// 验证冷凝管清洗参数
				if (cleaningParams.IsCondensationClean)
				{
					if (string.IsNullOrEmpty(cleaningParams.CondensationCleaningSolution))
						return (false, "请选择冷凝管清洗液");

					if (cleaningParams.CondensationCleaningVolume <= 0)
						return (false, "冷凝管清洗体积必须大于0");

					if (cleaningParams.CondensationCleaningSpeed <= 0)
						return (false, "冷凝管清洗速度必须大于0");
				}

				// 验证旋转瓶清洗参数
				if (cleaningParams.IsRotaryBottleClean)
				{
					if (string.IsNullOrEmpty(cleaningParams.RotaryBottleCleaningSolution))
						return (false, "请选择旋转瓶清洗液");

					if (cleaningParams.RotaryBottleCleaningVolume <= 0)
						return (false, "旋转瓶清洗体积必须大于0");

					if (cleaningParams.RotaryBottleCleaningTime <= 0)
						return (false, "旋转瓶清洗时间必须大于0");
				}
			}

			// 验证执行条件
			var (canExecute, message) = ValidateExecutionConditions(recipe);
			if (!canExecute)
				return (false, message);

			// 验证物料和清洗液是否存在
			var (materialsValid, materialsError) = await ValidateMaterialsExistenceAsync(recipe);
			if (!materialsValid)
				return (false, materialsError);

			return (true, string.Empty);
		}
		catch (Exception ex)
		{
			_logger.LogError(ex, "异步验证配方时发生错误");
			return (false, $"验证配方时发生错误: {ex.Message}");
		}
	}

	public async Task<(bool IsValid, string ErrorMessage)> ValidateProductParametersAsync(
		ObservableCollection<ProductParameters> parameters)
	{
		if (parameters == null || parameters.Count == 0)
			return (false, "至少需要一组产物参数");

		try
		{
			// 获取参数范围
			var oilTemperatureRange = await _deviceParameterService.GetOilTemperatureRangeAsync();
			var rotarySpeedRange = await _deviceParameterService.GetRotarySpeedRangeAsync();

			foreach (var param in parameters)
			{
				if (param.OilTemperature < oilTemperatureRange.Min || param.OilTemperature > oilTemperatureRange.Max)
					return (false, $"油浴温度 {param.OilTemperature} 超出有效范围({oilTemperatureRange.Min}-{oilTemperatureRange.Max}{oilTemperatureRange.Unit})");

				if (param.RotarySpeed < rotarySpeedRange.Min || param.RotarySpeed > rotarySpeedRange.Max)
					return (false, $"转速 {param.RotarySpeed} 超出有效范围({rotarySpeedRange.Min}-{rotarySpeedRange.Max}{rotarySpeedRange.Unit})");

				if (param.RotaryTime <= 0)
					return (false, $"旋蒸时间 {param.RotaryTime} 无效(应大于0)");
			}

			return (true, string.Empty);
		}
		catch (Exception ex)
		{
			_logger.LogError(ex, "验证产物参数时发生错误");

			// 如果获取参数范围失败，使用硬编码的默认值进行验证
			foreach (var param in parameters)
			{
				if (!ValidateTemperature(param.OilTemperature))
					return (false, $"油浴温度 {param.OilTemperature} 超出有效范围(0-300°C)");

				if (!ValidateRotarySpeed(param.RotarySpeed))
					return (false, $"转速 {param.RotarySpeed} 超出有效范围(0-200rpm)");

				if (!ValidateTime(param.RotaryTime))
					return (false, $"旋蒸时间 {param.RotaryTime} 无效(应大于0)");
			}

			return (true, string.Empty);
		}
	}

	// 保留同步方法以兼容现有代码
	public (bool IsValid, string ErrorMessage) ValidateProductParameters(
		ObservableCollection<ProductParameters> parameters)
	{
		// 调用异步方法并等待结果
		var task = ValidateProductParametersAsync(parameters);
		task.Wait();
		return task.Result;
	}

	private bool ValidateTemperature(double temperature) => temperature >= 0 && temperature <= 300;
	private bool ValidateRotarySpeed(double speed) => speed >= 0 && speed <= 200;
	private bool ValidateTime(double minutes) => minutes > 0;

	public TimeSpan CalculateTotalExecutionTime(RecipeDefinition recipe)
	{
		if (recipe?.RotovapParameters?.ProductParameters == null)
			return TimeSpan.Zero;

		var totalMinutes = recipe.RotovapParameters.ProductParameters.Sum(p => p.RotaryTime);
		return TimeSpan.FromMinutes(totalMinutes);
	}

	public (bool CanExecute, string Message) ValidateExecutionConditions(RecipeDefinition recipe)
	{
		if (recipe?.RotovapParameters?.MaterialLocations == null ||
			!recipe.RotovapParameters.MaterialLocations.Any())
			return (false, "未指定物料位置");

		// 添加其他执行条件验证
		return (true, string.Empty);
	}

	/// <summary>
	/// 验证物料和清洗液是否存在于货架上
	/// </summary>
	public async Task<(bool IsValid, string ErrorMessage)> ValidateMaterialsExistenceAsync(RecipeDefinition recipe)
	{
		try
		{
			if (recipe?.RotovapParameters == null)
			{
				return (false, "旋蒸参数不能为空");
			}

			// 验证物料名称和位置
			if (string.IsNullOrWhiteSpace(recipe.RotovapParameters.MaterialName))
			{
				return (false, "待旋蒸物料名称不能为空");
			}

			if (recipe.RotovapParameters.MaterialLocations == null ||
				recipe.RotovapParameters.MaterialLocations.Count == 0)
			{
				return (false, "请至少选择一个物料位置");
			}

			// 获取清洗参数
			string condensationCleaningSolution = string.Empty;
			string rotaryBottleCleaningSolution = string.Empty;

			if (recipe.RotovapParameters.CleaningParameters != null)
			{
				// 只有在选择了冷凝管清洗时，才验证冷凝管清洗液
				if (recipe.RotovapParameters.CleaningParameters.IsCondensationClean)
				{
					condensationCleaningSolution = recipe.RotovapParameters.CleaningParameters.CondensationCleaningSolution;
				}

				// 只有在选择了旋转瓶清洗时，才验证旋转瓶清洗液
				if (recipe.RotovapParameters.CleaningParameters.IsRotaryBottleClean)
				{
					rotaryBottleCleaningSolution = recipe.RotovapParameters.CleaningParameters.RotaryBottleCleaningSolution;
				}
			}

			// 使用存储领域服务验证物料和清洗液是否存在
			return await _storageDomainService.ValidateMaterialsExistenceAsync(
				recipe.RotovapParameters.MaterialName,
				condensationCleaningSolution,
				rotaryBottleCleaningSolution);
		}
		catch (Exception ex)
		{
			_logger.LogError(ex, "验证物料存在性时发生错误");
			return (false, $"验证物料存在性时发生错误: {ex.Message}");
		}
	}

	/// <summary>
	/// 验证实验组中的物料位置是否有重复
	/// </summary>
	/// <param name="recipes">配方列表</param>
	/// <returns>验证结果和错误信息</returns>
	public async Task<(bool IsValid, string ErrorMessage)> ValidateMaterialLocationsAsync(IEnumerable<RecipeDefinition> recipes)
	{
		try
		{
			if (recipes == null || !recipes.Any())
			{
				return (false, "配方列表不能为空");
			}

			// 收集所有物料位置
			var allLocations = new List<(int Location, string RecipeName, string MaterialName)>();

			foreach (var recipe in recipes)
			{
				if (recipe?.RotovapParameters?.MaterialLocations == null ||
					!recipe.RotovapParameters.MaterialLocations.Any())
				{
					continue; // 跳过没有物料位置的配方
				}

				foreach (var location in recipe.RotovapParameters.MaterialLocations)
				{
					allLocations.Add((location, recipe.ExperimentName, recipe.RotovapParameters.MaterialName));
				}
			}

			// 检查是否有重复的物料位置
			var duplicateLocations = allLocations
				.GroupBy(l => l.Location)
				.Where(g => g.Count() > 1)
				.ToList();

			if (duplicateLocations.Any())
			{
				var errorMessages = new List<string>();
				foreach (var group in duplicateLocations)
				{
					var locationInfo = string.Join(", ", group.Select(l => $"配方'{l.RecipeName}'的物料'{l.MaterialName}'"));
					errorMessages.Add($"物料位置 {group.Key} 被多个配方使用: {locationInfo}");
				}

				return (false, string.Join(Environment.NewLine, errorMessages));
			}

			return (true, string.Empty);
		}
		catch (Exception ex)
		{
			_logger.LogError(ex, "验证物料位置时发生错误");
			return (false, $"验证物料位置时发生错误: {ex.Message}");
		}
	}
}